<script setup>

import {inject, nextTick, onMounted, ref} from "vue";
import ChatService from "@/service/impl/ChatService.js";


const message = inject('message')
const props = defineProps({
    agents: {
        type: Object,
        default: null
    }
})
const chatConfig = ref({
    topK: 5,
    similarityThreshold: 0.5,
    contextLength: 100,
    prompt: "",
    enableSynergism: false,
})
const data = ref({
    id: null,
    agentsId: null,
    name: null,
    content: []
})
const msg = ref('')
const emit = defineEmits(['onTitleRefresh'])
const loding = ref(false)
const msgTemplate = {
    key: null,
    role: null,
    placement: 'start',
    content: null, // 消息内容 流式接受的时候，只需要改这个值即可
    loading: false, // 当前气泡的加载状态
    shape: 'round', // 气泡的形状
    variant: 'filled', // 气泡的样式
    isMarkdown: true, // 是否渲染为 markdown
    typing: false, // 是否开启打字器效果 该属性不会和流式接受冲突
    isFog: false, // 是否开启打字雾化效果，该效果 v1.1.6 新增，且在 typing 为 true 时生效，该效果会覆盖 typing 的 suffix 属性
    maxWidth: '90%',
    avatar: null,
    avatarSize: '0px', // 头像占位大小
    avatarGap: '10px' // 头像与气泡之间的距离
}

const onSelect = (item) => {
    // 执行查询
    loding.value = true
    ChatService.modeContentInfo(item).then(res => {
        data.value = res.data
        data.value.content = res.data.content.map((item,idx) => Object.assign({},msgTemplate, {
            key:idx,
            role: item.role,
            placement: item.role === 'system'? 'start' : 'end',
            content: item.content,
        }))
        loding.value = false
    }).catch(e => {
        loding.value = false
    })
}
const onClear = (item, all) => {
    if (item.id === data.value.id) {
        onBuildChat()
    }
    if (all) {
        onBuildChat()
    }
}
const onSend = () => {
    let id = props.agents?.id
    if (!id) {
        message.warning("请选择模式")
        return
    }
    if (msg.value === null || msg.value.trim() === '') {
        return;
    }
    ChatService.modeContentEdit({
        agentsId: id,
        message: msg.value,
        contentId: data.value.id
    }).then(res => {
        let m = msg.value
        msg.value = ''
        if (data.value.id === null) {
            emit('onTitleRefresh', res.data)
        }
        data.value.id = res.data.id
        data.value.content.push(Object.assign({},msgTemplate, {
            key: data.value.content.length + 1,
            role: 'user',
            content: m,
            placement:'end',
        }))
        let answer = ref(Object.assign({},msgTemplate, {
            key: data.value.content.length + 1,
            role: 'system',
            content: '',
            loading: true
        }))
        data.value.content.push(answer.value)
        ChatService.question({
            agentsId: id,
            message: m,
            contentId: res.data.id,
            agents: props.agents,
            chatConfig: chatConfig.value
        }, (data) => {
            answer.value.loading = false
            answer.value.content += data
        }, (tag) => {
            // console.log(tag)
        })
    }).catch(e => {

    })
}
const onBuildChat = () => {
    data.value = {
        id: null,
        agentsId: null,
        name: null,
        content: []
    }
}
const onCancel = () => {
    msg.value = ''
}
defineExpose({
    onSelect, onClear,
})
onMounted(() => {

})

</script>

<template>
    <el-row class="main">
        <el-row class="chat">
<!--            <XMarkdown v-for="item in data.content" :markdown="item.content" class="vp-raw" />-->
            <BubbleList class="chat-top" :list="data.content" >
                <template #content="{ item }">
                    <!-- chat 内容走 markdown -->
                    <XMarkdown v-if="item.content && item.role === 'system'" :markdown="item.content" class="system-content" />
                    <!-- user 内容 纯文本 -->
                    <div v-if="item.content && item.role === 'user'" >
                        {{ item.content }}
                    </div>
                </template>
            </BubbleList>
            <Sender class="chat-bottom" ref="senderRef" v-model="msg"
                    :auto-size="{ minRows: 3, maxRows: 3 }" allow-speech
                    :loading="false" clearable @submit="onSend" @cancel="onCancel" />
        </el-row>
        <el-row class="modulation">
            <el-form style="width: 100%;padding: 5px" label-position="top">
                <el-form-item label="提示词">
                    <el-input
                        style="font-size: 14px;height: calc(14px * 10 * 1.55)"
                        v-model="chatConfig.prompt"
                        type="textarea"
                        :rows="10"
                        placeholder=""
                        resize="none"
                    />
                </el-form-item>
                <el-form-item label="查询文档数量">
                    <el-input v-model="chatConfig.topK"/>
                </el-form-item>
                <el-form-item label="文档相似度" >
                    <el-slider style="margin-left: 5%;width: 90%;" v-model="chatConfig.similarityThreshold" :min="0" :max="1" :step="0.1"/>
                </el-form-item>
                <el-form-item label="上下文长度">
                    <el-input v-model="chatConfig.contextLength"/>
                </el-form-item>
                <el-form-item label="">
                    <el-form-item label="启用协同">
                        <el-switch
                            v-model="chatConfig.enableSynergism"
                            :active-value="true"
                            :inactive-value="false"
                        />
                    </el-form-item>
<!--                    <el-form-item label="启用MCP">-->
<!--                        <el-switch-->
<!--                            v-model="chatConfig.enableMCP"-->
<!--                            :active-value="true"-->
<!--                            :inactive-value="false"-->
<!--                        />-->
<!--                    </el-form-item>-->
                </el-form-item>

            </el-form>
        </el-row>
    </el-row>
</template>

<style scoped lang="scss">
.main {
    width: 100%;
    height: 100%;
    float: left;
}

.chat {
    height: 100%;
    width: calc(100% - 300px);
    float: left;

    .chat-top {
        height: 100%;
        width: 100%;
        padding: 10px 0;
        overflow-y: auto;
        display: flex;
        align-content: start;

        .chat-bubble {
            position: relative;
            max-width: 70%;
            padding: 10px;
            border-radius: 10px;
            word-wrap: break-word;
        }

        .chat-bubble.sent {
            background-color: #DCF8C6;
            color: #333;
            margin-left: 15px;
        }

        .chat-bubble.sent::after {
            content: "";
            position: absolute;
            top: 10px;
            left: -17px;
            border-width: 10px;
            border-style: solid;
            border-color: transparent #DCF8C6 transparent transparent;
        }

        .chat-bubble.received {
            background-color: #E5E5EA;
            color: #333;
        }

        .chat-bubble.received::after {
            content: "";
            position: absolute;
            top: 10px;
            right: -16px;
            border-width: 10px;
            border-style: solid;
            border-color: transparent transparent transparent #E5E5EA;
        }

    }

    .chat-bottom {
        margin-top: 25px;
        width: 100%;
    }

    .system-content{
        background-color: transparent;
        padding:0 !important;
        :deep(p) {
            margin: 0 !important;
            padding: 0 !important;
            line-height: 2;
            letter-spacing: 0.5px;
        }
    }

}

.modulation {
    width: 290px;
    height: 100%;
    float: right;
    border: 1px solid var(--el-menu-border-color);
    margin-left: 10px;
    overflow-y: auto;
}
</style>


